home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.tar / ftp.whtech.com / datasheets and manuals / Hardware / WHT / scsi / dsr_sources_2_2001 / read < prev    next >
Text File  |  2006-10-19  |  24KB  |  975 lines

  1. * I/O Opcode 2 - READ
  2. *
  3. * This routine will store the next record of the specified file
  4. * in the user's buffer provided
  5. *   1. The file is open
  6. *   2. We have not reached end of file yet
  7. *
  8. * Once it determines that the file is open and not at end of file,
  9. * it must determine if the contents of the buffer is valid.  If not,
  10. * it will read the next sector from the disk.  If convient, it will
  11. * read 2 sectors and use all 512 bytes of the buffer.
  12. *
  13. * Date: April 22, 1995
  14. * Author: David Nieters
  15. *
  16. * Well, it's less than one week till Lima and I'm still writing
  17. * new code.  Let's home I get some of this working in time so it
  18. * looks like it's 90% done like Don has been telling everybody.
  19. *
  20. * Modification History
  21. *
  22. * November 20, 1995 - Fixed directory file access to return the
  23. *      exact length for each filename instead of padded with
  24. *      spaces.  Also, returns a null string when reached the
  25. *      end instead of 10 spaces.  Will add subdirectory listings
  26. *      later.
  27. *
  28.  
  29. READ0
  30.        ANDI R12,>FF00
  31.        AI   R12,24
  32.  
  33.        LDCR @B02,4            Select RAM bank 2
  34.        BLWP @IFO              Check to make sure file is open
  35.        JEQ  READ2
  36.  
  37. READ1  BL   @DSRERR
  38.        DATA >0700             File error
  39.  
  40. READ2  CB   @56(R5),@B02      See if file has been opened for reading
  41.        JEQ  READ3
  42.        CB   @56(R5),@ZERO     or update access
  43.        JEQ  READ3
  44.        CB   @56(R5),@B05      Or directory access
  45.        JEQ  READ3A
  46.  
  47.        BL   @DSRERR
  48.        DATA >0200             Bad open attribute?
  49.  
  50. READ3A B    @READ60           Handle directory read
  51.  
  52. READ4  B    @READ50           Handle the relative read
  53.  
  54. READ3  LDCR @ZERO,4           Check for sequential access
  55.        MOVB @PABBUF+1,R1      Get flags
  56.        ANDI R1,>0100
  57.        JNE  READ4
  58.  
  59.        LDCR @B02,4
  60.  
  61.  
  62. * We know that the file is open and we are reading sequentially.
  63. * Now check to see if we're at end of file.
  64. *
  65.        MOV  @4(R5),R1         Get FDR address
  66.        MOV  @62(R5),R2        Get sector/record number
  67.        MOV  @54(R5),R3        Get the pointer within the buffer
  68.  
  69.        LDCR @2(R5),4          Select BANK with FDR
  70.  
  71. * If the file is empty, we must be reading
  72. * past the end of file.
  73.  
  74.        C    @ZERO,@18(R1)
  75.        JEQ  READ5
  76.  
  77.        SWPB R2
  78.        C    R2,@18(R1)        See if we're in the last sector written
  79.        JNE  READ7
  80.  
  81. * Here we check for fixed or variable length records.  If fixed,
  82. * the value in R2 was the last record written and we know we're
  83. * at the end of the file.  It the records are variable length, we
  84. * check to see if we're pointing to an end of sector marker.
  85. *
  86.  
  87.        MOVB @12(R1),R0        Check for fixed or variable length
  88.        ANDI R0,>8000
  89.        JNE  READ6
  90.  
  91. READ5
  92.        LDCR @B02,4           Close file if attempting to
  93.        CLR  @4(R5)           read past end of file
  94.  
  95.        BL   @DSRERR
  96.        DATA >0500             Attempt to read past end of file
  97.  
  98. READ6  LDCR @B02,4            Select RAM bank 2
  99.        LDCR @3(R5),4          Select bank with buffer
  100.        CB   *R3,@B255         Are we at the end of the sector?
  101.        JEQ  READ5
  102.  
  103. READ7  LDCR @B02,4            Select RAM bank 2
  104.        C    @50(R5),@ZERO     Have we read the 1st sector yet?
  105.        JNE  READ20
  106.  
  107. * We have to read in the 1st sector of the file
  108. *
  109.        LDCR @2(R5),4          Select bank with the FDR in it
  110.        MOV  @40(R1),R7        Get 1st AU allocate in file
  111.        LDCR @B02,4            Select RAM bank 2
  112.        MOV  R7,@50(R5)        Save current AU
  113.        CLR  @52(R5)           We're reading 1st sector if this AU
  114.        CLR  @58(R5)           Set buffer size to 256 for now
  115.        MOV  @6(R5),@54(R5)    Set pointer to beginning of buffer
  116.  
  117.        LDCR @B04,4            Select RAM bank 4
  118.        MOV  R6,R3
  119.        SRL  R3,8
  120.        SLA  R3,1
  121.        MOV  @SAUTBL(R3),R3    Get the Sectors/AU for this disk
  122.        MPY  R3,R7
  123.        LI   R1,SECBUF
  124.        SRL  R8,1
  125.        JNC  READ8
  126.        AI   R1,>100
  127. READ8  SRL  R7,1
  128.        JNC  READ9
  129.        AI   R8,>8000
  130. READ9  LDCR @ZERO,4
  131.        BLWP @BANKIT
  132.        DATA SCSIRD
  133.        JEQ  READ10
  134.        BL   @DSRERR
  135.        DATA >0600             Device error
  136.  
  137. * Now that we have read the block from the disk, see if we
  138. * can use all 512 bytes, or only 256
  139. *
  140. READ10 LDCR @B02,4            Select RAM bank 2
  141.        CI   R3,2              Make sure Sectors/AU > 1
  142.        JL   READ11
  143.        CI   R1,SECBUF         Make sure we start at beginning
  144.        JNE  READ11
  145.  
  146.        SETO @58(R5)           We're using all 512 bytes!
  147. READ11
  148.        MOV  @6(R5),R2         Get buffer address
  149.        MOVB @3(R5),R3         Get buffer bank number
  150. READ12 LDCR @ZERO,4           Select RAM bank 0
  151.        MOV  *R1+,R0
  152.        LDCR R3,4
  153.        MOV  R0,*R2+
  154.        CI   R1,SECBUF+512
  155.        JNE  READ12
  156.  
  157.        LDCR @B02,4            Select RAM bank 2
  158.        MOV  @4(R5),R1         Get FDR address
  159.        LDCR @2(R5),4
  160.        MOVB @12(R1),R0        Set sector # to 1 if a variable file
  161.        ANDI R0,>8000
  162.        JEQ  READ13
  163.        LDCR @B02,4
  164.        INC  @62(R5)
  165. READ13
  166.        B    @READ40
  167.  
  168.  
  169. *****************************************************
  170. *
  171. *  Here we want to check to see if the buffer is
  172. *  valid.  If it is not, then we must read the
  173. *  next sector into the buffer.
  174. *
  175. *****************************************************
  176.  
  177. READ20
  178.        LDCR @B02,4            Select RAM bank 2
  179.        MOV  @4(R5),R1         Get pointer FDR
  180.  
  181.        LDCR @2(R5),4
  182.        MOVB @12(R1),R2        Get file flags
  183.        LDCR @B02,4            Select RAM bank 2
  184.        ANDI R2,>8000          See if we have fixed length records
  185.        JNE  READ2C
  186.        B    @READ39
  187. READ2C
  188.        MOV  @54(R5),R1        Get pointer in buffer
  189.        LDCR @3(R5),4          Select bank with buffer in it
  190.        CB   *R1,@B255         If it starts with >FF, it's end of sector
  191.        JEQ  READ2B
  192.        B    @READ40
  193. READ2B
  194.        LDCR @B02,4            Select RAM bank 2
  195.        INC  @62(R5)           Increment sector number
  196.  
  197. * We're at the end of the sector.  If we have a 512 byte buffer and
  198. * we're still in the first 256 bytes, just go to second half of
  199. * buffer.  Otherwise, read the next sector from the disk.
  200. *
  201. READ21
  202.        LDCR @B02,4            Select RAM bank 2
  203.        C    @58(R5),@ZERO     See if we have a 512 byte buffer
  204.        JEQ  RD21A
  205.        MOV  @54(R5),R1        See if we're in 1st half of buffer
  206.        ANDI R1,>0100
  207.        JNE  RD21A
  208.  
  209.        MOV  @54(R5),R1        OK, just go to next half
  210.        ANDI R1,>FF00
  211.        AI   R1,>100
  212.        MOV  R1,@54(R5)        Save new pointer
  213.        INC  @52(R5)           Increment sector counter
  214.        LDCR @B04,4            Select RAM bank 4
  215.        MOV  R6,R3
  216.        SRL  R3,8
  217.        SLA  R3,1
  218.        MOV  @SAUTBL(R3),R3
  219.        LDCR @B02,4            Select RAM bank 2
  220.        C    R3,@52(R5)        See if we transcended an AU boundry
  221.        JNE  RD21B
  222.        CLR  @52(R5)           Clear sector within AU
  223.        INC  @50(R5)           increment AU number
  224. RD21B  B    @READ40
  225.  
  226.  
  227. * Well, it looks like we're going to have to read the
  228. * next sector from disk
  229. *
  230. RD21A
  231.        LDCR @B04,4            Select RAM bank 4
  232.        MOV  R6,R3
  233.        SRL  R3,8
  234.        SLA  R3,1
  235.        MOV  @SAUTBL(R3),R3
  236.        LDCR @B02,4            Select RAM bank 2
  237.        MOV  @50(R5),R7        Get current AU
  238.        INC  @52(R5)           go to next sector within AU
  239.        C    @52(R5),R3        See if we need to go to next AU
  240.        JNE  READ25
  241.  
  242. * If this was the last AU in the cluster, we must go
  243. * to the next cluster.  Otherwise, just increment
  244. * the current AU.
  245.  
  246.        CLR  @52(R5)
  247.        MOV  @4(R5),R1         Get FDR address
  248.        LDCR @2(R5),4          Select bank with FDR
  249.        LI   R10,54            There are 54 total clusters/FDR
  250.        AI   R1,42
  251. READ22 MOV  *R1+,R2
  252.        JEQ  READ23
  253.        C    R2,R7
  254.        JEQ  READ24
  255.        INCT R1
  256.        DEC  R10
  257.        JNE  READ22
  258. READ23 INC  R7
  259.        JMP  READ25
  260.  
  261. READ24 MOV  *R1,R7
  262. READ25
  263.        LDCR @B02,4            Select RAM bank 2
  264.        MOV  R7,@50(R5)        Save current AU
  265.        MOV  @6(R5),@54(R5)    Reset pointer in buffer
  266.        CLR  @58(R5)           Set buffer size to 256 byte (for now)
  267.        MPY  R3,R7
  268.        A    @52(R5),R8        Add in sector within AU
  269.        JNC  READ26
  270.        INC  R7
  271. READ26 LI   R1,SECBUF
  272.        SRL  R8,1
  273.        JNC  READ27
  274.        AI   R1,>100
  275. READ27 SRL  R7,1
  276.        JNC  READ28
  277.        AI   R8,>8000
  278. READ28 LDCR @ZERO,4           Select RAM bank 0
  279.        BLWP @BANKIT           Read the sector from disk
  280.        DATA SCSIRD
  281.        JEQ  READ29
  282.        BL   @DSRERR
  283.        DATA >0600             Device error
  284.  
  285. READ29
  286.        LDCR @B02,4
  287.        CI   R3,2              See if we can use a 512 byte buffer
  288.        JL   RD29A
  289.        CI   R1,SECBUF
  290.        JNE  RD29A
  291.        SETO @58(R5)
  292. RD29A
  293.        MOV  @6(R5),R2         Get buffer address
  294.        MOVB @3(R5),R4
  295.  
  296. READ30 LDCR @ZERO,4           Select RAM bank 0
  297.        MOV  *R1+,R10
  298.        LDCR R4,4
  299.        MOV  R10,*R2+
  300.        CI   R1,SECBUF+512
  301.        JNE  READ30
  302.        JMP  READ40
  303.  
  304. R21HLP B    @RD21A            Help the JH instruction below
  305. R22HLP B    @READ21
  306.  
  307. * If we are handling fixed length records, we handle the
  308. * buffer validity a little differently.  Here goes
  309.  
  310. * If the pointer is exactly >200 greater than the base,
  311. * we know we have to read the next sector.  If it is
  312. * exactly >100 greater than the base and the buffer size
  313. * is 256 bytes, we have to read the next sector.
  314.  
  315. READ39 LDCR @B02,4            Select RAM bank 2
  316.        MOV  @54(R5),R1        Get pointer within buffer
  317.        S    @6(R5),R1         Subtract the base address
  318.        CI   R1,>200
  319.        JEQ  R21HLP
  320.        CI   R1,>100
  321.        JNE  RD39A
  322.        C    @58(R5),@ZERO     See if buffer size is 256
  323.        JEQ  R21HLP            If so, read next sector
  324.        INC  @52(R5)
  325.  
  326. RD39A  MOV  @54(R5),R1        Get pointer within buffer
  327.  
  328.        ANDI R1,>00FF
  329.        MOV  @4(R5),R2         Get FDR address
  330.        LDCR @2(R5),4          Select bank with FDR
  331.        MOVB @17(R2),R4        Get record length
  332.        SRL  R4,8
  333.        A    R4,R1             See if we can add record length
  334.        CI   R1,>0100          Without going over
  335.        JH   R22HLP            If not, read next sector
  336.  
  337.  
  338. * We know the buffer is good.  All we have to do now is
  339. * transfer the record to the user's buffer.
  340.  
  341. READ40
  342.  
  343. * If we have a fixed length record, read that many bytes.
  344. * If we have a variable length record, read the length
  345. * byte first and read that many bytes.
  346. *
  347.        LDCR @B02,4            Select RAM bank 2
  348.        MOV  @54(R5),R2        Get buffer pointer
  349.        MOVB @3(R5),R3         Get buffer bank
  350.        MOV  @4(R5),R1         Get Address of FDR
  351.        LDCR @2(R5),4          Select bank where FDR is
  352.        MOVB @12(R1),R0
  353.        ANDI R0,>8000          Mask out fixed/variable bit
  354.        JEQ  READ44
  355.  
  356. * Well, we have a variable length record.  Read the record
  357. * size byte and store that many characters in the user's
  358. * buffer.
  359. *
  360.        LDCR R3,4
  361.        MOVB *R2+,R0
  362. READ41
  363.        LDCR @ZERO,4      Store record size in user's PAB
  364.        MOV  @PABADR,R1
  365.        ORI  R1,>4000
  366.        AI   R1,5
  367.        SWPB R1
  368.        MOVB R1,@VDPWA
  369.        SWPB R1
  370.        MOVB R1,@VDPWA
  371.        NOP
  372.        MOVB R0,@VDPWD
  373.  
  374.        JEQ  READ43            Skip copy if a null record
  375.        SRL  R0,8
  376.  
  377. * Set the VDP write address to the user's buffer
  378. *
  379.        MOV  @PABBUF+2,R1
  380.        ORI  R1,>4000
  381.        SWPB R1
  382.        MOVB R1,@VDPWA
  383.        SWPB R1
  384.        MOVB R1,@VDPWA
  385.  
  386.        LDCR R3,4
  387.  
  388. READ42 MOVB *R2+,@VDPWD
  389.        DEC  R0
  390.        JNE  READ42
  391.  
  392. READ43 LDCR @B02,4
  393.        MOV  R2,@54(R5)
  394.        LDCR @ZERO,4
  395.        B    @DSRRT
  396.  
  397. READ44 MOVB @17(R1),R0        Get fixed record length
  398.        LDCR @B02,4            Select RAM bank 2
  399.        INC  @62(R5)           Increment last record # read.
  400.        JMP  READ41
  401.  
  402.  
  403. READ49 BL   @DSRERR
  404.        DATA >0500            Attempt to read past end of file
  405. **
  406. *
  407. * Here is where we handle relative access reads.  The trick involves
  408. * several divisions to compute where the record fits in the file.
  409. *
  410. **
  411.  
  412. READ50
  413.        BL   @POSIT
  414.        LDCR @ZERO,4
  415.        MOV  @PABADR,R1       Increment record # in caller's PAB
  416.        ORI  R1,>4000
  417.        AI   R1,6
  418.        SWPB R1
  419.        MOVB R1,@VDPWA
  420.        SWPB R1
  421.        MOVB R1,@VDPWA
  422.        MOV  @PABBUF+6,R1
  423.        INC  R1
  424.        MOVB R1,@VDPWD
  425.        SWPB R1
  426.        MOVB R1,@VDPWD
  427.  
  428.        B    @READ40          Transfer record to user and return
  429.  
  430. **
  431. *
  432. * Here is where we handle directory reads.  Record 0 is the
  433. * directory itself.  Records 1-127 are files.
  434. *
  435. **
  436.  
  437. READ60
  438.  
  439. * Store the # of characters written in the caller's PAB
  440. *
  441.  
  442.        LDCR @ZERO,4           Select RAM bank 0
  443.        MOV  @PABADR,R1
  444.        ORI  R1,>4000
  445.        AI   R1,5
  446.        SWPB R1
  447.        MOVB R1,@VDPWA
  448.        SWPB R1
  449.        MOVB R1,@VDPWA
  450.        LI   R0,38*256          Store record length
  451.        MOVB R0,@VDPWD
  452.  
  453. * Set the VDP write address to the user's buffer
  454. *
  455.        MOV  @PABBUF+2,R1
  456.        ORI  R1,>4000
  457.        SWPB R1
  458.        MOVB R1,@VDPWA
  459.        SWPB R1
  460.        MOVB R1,@VDPWA
  461.  
  462. * See which record we are reading
  463. *
  464.        MOVB @PABBUF+1,R1
  465.        ANDI R1,>0100
  466.        JEQ  READ61
  467.  
  468.        MOV  @PABADR,R1       Increment record # in caller's PAB
  469.        ORI  R1,>4000
  470.        AI   R1,6
  471.        SWPB R1
  472.        MOVB R1,@VDPWA
  473.        SWPB R1
  474.        MOVB R1,@VDPWA
  475.        MOV  @PABBUF+6,R1
  476.        INC  R1
  477.        MOVB R1,@VDPWD
  478.        SWPB R1
  479.        MOVB R1,@VDPWD
  480.  
  481.        MOV  @PABBUF+2,R1
  482.        ORI  R1,>4000
  483.        SWPB R1
  484.        MOVB R1,@VDPWA
  485.        SWPB R1
  486.        MOVB R1,@VDPWA
  487.  
  488.        MOV  @PABBUF+6,R1
  489.        JMP  READ62
  490.  
  491. READ61 LDCR @B02,4           Sequential read, get from cache
  492.        MOV  @62(R5),R1
  493.        INC  @62(R5)
  494. READ62
  495.        CI   R1,0             See if reading directory
  496.        JNE  READ70
  497.  
  498. * Copy the directory name to the user's buffer
  499. *
  500.        LDCR @B02,4
  501.        MOV  @4(R5),R4
  502.        LDCR @2(R5),4
  503.        LI   R0,10
  504.        AI   R4,9
  505. READ63 CB   *R4,@SPACE
  506.        JNE  RD63A
  507.        DEC  R4
  508.        DEC  R0
  509.        JNE  READ63
  510.  
  511. RD63A  SWPB R0
  512.        MOVB R0,@VDPWD        Set name length
  513.        JEQ  RD63C
  514.        SWPB R0
  515.        S    R0,R4
  516.        INC  R4
  517. RD63B  MOVB *R4+,@VDPWD
  518.        DEC  R0
  519.        JNE  RD63B
  520. RD63C
  521. * Now get the rest of the info
  522. *   R8 = Record type (Always zero)
  523. *   R9 = Total # of AU's on the disk
  524. *   R10 = # of free AU's on the disk
  525.  
  526. * Now get the number of free AU's on the disk.  We read the
  527. * entire bitmap from disk and count the number of zeros.
  528. * There's got to be a better way to do this, and when I
  529. * think of it, I'll change this code.
  530. *
  531.        CLR  R7
  532.        CLR  R8
  533.        LI   R4,SECBUF+>100   The bitmap is right after VIB
  534.        CLR  R10              R10 Keeps track of # of free AU's
  535.        LDCR @ZERO,4
  536.  
  537. READ64 BLWP @BANKIT
  538.        DATA SCSIRD
  539.        JEQ  READ65
  540.  
  541.        AI   R8,16            If error, read copy
  542.        BLWP @BANKIT
  543.        DATA SCSIRD
  544.        AI   R8,-16
  545. READ65
  546. * If the value is 0, we can just add 16 to the number of
  547. * free AU's.  Otherwise, we have to count the bits in R1.
  548.  
  549. * If we just read the VIB, get the disk size here
  550.  
  551.        CI   R8,0
  552.        JNE  RD65A
  553.        MOV  @SECBUF+10,R5    Save in R5 for now
  554.        MOV  @SECBUF+16,R2    Get sectors/AU
  555.        SRL  R2,12
  556.        INC  R2
  557. RD65A
  558.        MOV  *R4+,R1
  559.        JNE  READ68
  560.  
  561.        AI   R10,16
  562. READ66 CI   R4,SECBUF+>200
  563.        JNE  RD65A
  564.  
  565. READ67 LI   R4,SECBUF
  566.        INC  R8
  567.        CI   R8,16
  568.        JNE  READ64
  569.  
  570. * Now report the disk size and free space.  We use
  571. * the new 20 bit integer routine for this!
  572.  
  573.        MOV  R2,R9            Store Sectors/AU in another REG
  574.        CLR  R1               File type = 0
  575.        CLR  R2
  576.        BL   @I20TOR
  577.  
  578.        MOV  R5,R1            Disk size in AU's
  579.        MPY  R9,R1
  580.        BL   @I20TOR
  581.  
  582.        MOV  R10,R1
  583.        MPY  R9,R1
  584.        BL   @I20TOR
  585.  
  586.        LDCR @ZERO,4
  587.        B    @DSRRT
  588.  
  589. READ68 CI   R1,-1
  590.        JEQ  READ66
  591.        LI   R0,16
  592. READ69 SLA  R1,1
  593.        JOC  RD69A
  594.        INC  R10
  595. RD69A  DEC  R0
  596.        JNE  READ69
  597.        JMP  READ66
  598.  
  599.  
  600. * READ80  We're past all the filenames, return
  601. * information on subdirectories now.
  602. *
  603. READ80 S    R3,R1            Subtract # of files
  604.        MOVB @23(R2),R3       Get # of subdirectories
  605.        SRL  R3,8
  606.        C    R1,R3
  607.        JH   READ81
  608.        B    @READ91
  609.  
  610. READ81 CLR  @VDPWD           String length
  611.        LI   R1,3             Return 3 RAXID 100 numbers
  612.        LI   R2,>0808
  613. READ82 MOV  R2,@VDPWD
  614.        LI   R3,8
  615. READ83 CLR  @VDPWD
  616.        DEC  R3
  617.        JNE  READ83
  618.        DEC  R1
  619.        JNE  READ82
  620.        LDCR @ZERO,4
  621.        B    @DSRRT
  622. **
  623. *
  624. * Here we are retrieving information about a file.  If the
  625. * record number is out of range, return all zeros.
  626. *
  627. **
  628.  
  629. READ70 LDCR @B02,4
  630.        MOV  @4(R5),R2        Get DDR address
  631.        LDCR @2(R5),4
  632.  
  633.        MOVB @22(R2),R3       Get # of files in directory
  634.        SRL  R3,8
  635.        C    R1,R3
  636.        JH   READ80
  637.  
  638. * See if the FDIR has been loaded into the buffer.  If it
  639. * hasn't, read it in now
  640.  
  641.        MOV  @24(R2),R7       Get AU of FDIR just in case
  642.        LDCR @B02,4
  643.        C    @58(R5),@ZERO
  644.        JNE  READ75
  645.  
  646.        SETO @58(R5)          Set flag
  647.        MOV  R6,R3            Read FDIR
  648.        SRL  R3,8
  649.        SLA  R3,1
  650.        LDCR @B04,4
  651.        MPY  @SAUTBL(R3),R7
  652.        LI   R2,SECBUF
  653.        SRL  R8,1
  654.        JNC  READ71
  655.        AI   R2,>100
  656. READ71 SRL  R7,1
  657.        JNC  READ72
  658.        AI   R8,>8000
  659. READ72 LDCR @ZERO,4
  660.        BLWP @BANKIT
  661.        DATA SCSIRD
  662.  
  663.        JEQ  READ73
  664.        BL   @DSRERR
  665.        DATA >0600
  666.  
  667. READ73 LDCR @B02,4
  668.        MOV  @6(R5),R3        Get buffer address
  669.        MOVB @3(R5),R4        Get buffer Bank
  670.        LI   R0,256
  671.  
  672. READ74 LDCR @ZERO,4
  673.        MOV  *R2+,R7
  674.        LDCR R4,4
  675.        MOV  R7,*R3+
  676.        DECT R0
  677.        JNE  READ74
  678.  
  679. READ75
  680.        DEC  R1
  681.        SLA  R1,1
  682.        LDCR @B02,4
  683.        MOV  @6(R5),R4        Get address of buffer
  684.        LDCR @3(R5),4
  685.  
  686.        A    R1,R4
  687.        MOV  *R4,R7           Get AU of FDR
  688.  
  689.        LI   R1,SECBUF
  690.        MOV  R6,R3
  691.        SRL  R3,8
  692.        SLA  R3,1
  693.        LDCR @B04,4
  694.        MPY  @SAUTBL(R3),R7
  695.        SRL  R8,1
  696.        JNC  READ76
  697.        AI   R1,>100
  698. READ76 SRL  R7,1
  699.        JNC  READ77
  700.        AI   R8,>8000
  701. READ77 LDCR @ZERO,4
  702.        BLWP @BANKIT
  703.        DATA SCSIRD
  704.        JEQ  READ78
  705.        BL   @DSRERR
  706.        DATA >0600
  707.  
  708. READ78 LI   R0,10            Copy filename to user's buffer
  709.        MOV  R1,R9
  710.        AI   R1,9
  711. RD78A  CB   *R1,@SPACE
  712.        JNE  RD78B
  713.        DEC  R1
  714.        DEC  R0
  715.        JNE  RD78A
  716. RD78B  SWPB R0
  717.        MOVB R0,@VDPWD        File length shouldn't be zero
  718.        JEQ  RD79Z            but just in case...
  719.        SWPB R0
  720.        MOV  R9,R1
  721. READ79 MOVB *R1+,@VDPWD
  722.        DEC  R0
  723.        JNE  READ79
  724.  
  725. RD79Z  MOV  R9,R1
  726.  
  727.        MOV  @14(R1),R9       # of sectors allocated
  728.        MOVB @17(R1),R10      # of bytes/record
  729.        SRL  R10,8
  730.  
  731. * Now see what type of file it is.  We return the following
  732. *
  733. * 1: Display/Fixed
  734. * 2: Display/Variable
  735. * 3: Internal/Fixed
  736. * 4: Internal/Variable
  737. * 5: Program file
  738. *
  739. * If the file is protected, these numbers are inverted
  740.  
  741.        LI   R8,5
  742.        MOVB @12(R1),R0
  743.        ANDI R0,>0100     Check for program file
  744.        JNE  RD79B
  745.        LI   R8,1         Assume Display/Fixed
  746.        MOVB @12(R1),R0
  747.        ANDI R0,>8000     Check for variable records
  748.        JEQ  RD79A
  749.        INC  R8
  750. RD79A  MOVB @12(R1),R0
  751.        ANDI R0,>0200     Check for internal
  752.        JEQ  RD79B
  753.        INCT R8
  754. RD79B
  755.  
  756. * Now check to see if the file is protected
  757.        MOV  @12(R1),R0
  758.        COC  @PROBIT,R0
  759.        JNE  RD79C
  760.        NEG  R8
  761. RD79C
  762.  
  763. * Now we just have to convert some 16 bit integers to radix 100
  764. * format and store in the user's buffer and go home.
  765. *
  766. READ90
  767.        MOV  R8,R2
  768.        BL   @ITORAD
  769.        MOV  R9,R2
  770.        BL   @ITORAD
  771.        MOV  R10,R2
  772.        BL   @ITORAD
  773.  
  774.        LDCR @ZERO,4
  775.        B    @DSRRT
  776.  
  777. **
  778. *
  779. * READ91 - Here we return information on a subdirectory
  780. *
  781. **
  782.  
  783. READ91 DEC  R1
  784.        SLA  R1,1
  785.        LDCR @B02,4
  786.        MOV  @4(R5),R4        Get address of DDR
  787.        LDCR @2(R5),4
  788.  
  789.        A    R1,R4
  790.        MOV  @28(R4),R7       Get AU of subdirectory DDR
  791.  
  792.        LI   R1,SECBUF
  793.        MOV  R6,R3
  794.        SRL  R3,8
  795.        SLA  R3,1
  796.        LDCR @B04,4
  797.        MPY  @SAUTBL(R3),R7
  798.        SRL  R8,1
  799.        JNC  READ92
  800.        AI   R1,>100
  801. READ92 SRL  R7,1
  802.        JNC  READ93
  803.        AI   R8,>8000
  804. READ93 LDCR @ZERO,4
  805.        BLWP @BANKIT
  806.        DATA SCSIRD
  807.        JEQ  READ94
  808.        BL   @DSRERR
  809.        DATA >0600
  810.  
  811. READ94 LI   R0,10            See how long the name is
  812.        MOV  R1,R9
  813.        AI   R1,9
  814. READ95 CB   *R1,@SPACE
  815.        JNE  READ96
  816.        DEC  R1
  817.        DEC  R0
  818.        JNE  READ95
  819. READ96 SWPB R0
  820.        MOVB R0,@VDPWD        Store directory name length
  821.        JEQ  READ98
  822.        SWPB R0
  823.        MOV  R9,R1
  824. READ97 MOVB *R1+,@VDPWD
  825.        DEC  R0
  826.        JNE  READ97
  827.  
  828. READ98 MOV  R9,R1
  829.        LI   R8,6             File type = 6 for directory
  830.        LI   R9,2             Size = 2 for now
  831.        CLR  R10              Record size = 0?
  832.        JMP  READ90
  833.  
  834. ************************************************************
  835. *                                                          *
  836. *  PROCEDURE ITORAD                                        *
  837. *                                                          *
  838. *  This procedure will take an unsigned integer stored in  *
  839. *  R1 and convert it to RADIX 100 and store the result in  *
  840. *  the file buffer.                                        *
  841. *                                                          *
  842. ************************************************************
  843.  
  844. ITORAD
  845.  
  846.        MOVB @B08,@VDPWD        Store field length (8 bytes)
  847.  
  848.        CI   R2,0
  849.        JEQ  ITOR00
  850.        CI   R2,100
  851.        JL   ITOR1
  852.        CI   R2,10000
  853.        JL   ITOR3
  854.  
  855. * If it is greater than 65530, assume it's negative
  856.        CI   R2,65530
  857.        JL   ITOR50
  858. *      NEG  R2
  859. *      ORI  R2,>4000
  860. *      NEG  R2
  861.        ANDI R2,>BFFF
  862.        MOVB R2,@VDPWD
  863.        SWPB R2
  864.        MOVB R2,@VDPWD
  865.        JMP  ITOR1A
  866.  
  867. * Here we are converting a number in the range of 10000-65535
  868. *
  869.  
  870. ITOR50
  871.        CLR  R1
  872. ITOR5A MOVB @HEX42,@VDPWD
  873.        LI   R0,4
  874. ITOR5B LI   R3,10000
  875.        DIV  R3,R1
  876.        SWPB R1
  877.        MOVB R1,@VDPWD
  878.        CLR  R1
  879.        LI   R3,100
  880.        DIV  R3,R1
  881.        SWPB R1
  882.        MOVB R1,@VDPWD
  883.        SWPB R2
  884.        MOVB R2,@VDPWD
  885.        JMP  ITOR2
  886.  
  887. * Here we are doing the number 0
  888. *
  889. ITOR00 LI   R0,8
  890.        JMP  ITOR2
  891.  
  892. * Here are are converting a number in the range of 0-99
  893. *
  894. ITOR1
  895.        MOVB @HEX40,@VDPWD
  896.        SWPB R2
  897.        MOVB R2,@VDPWD
  898. ITOR1A LI   R0,6
  899. ITOR2  CLR  @VDPWD
  900.        DEC  R0
  901.        JNE  ITOR2
  902.        RT
  903.  
  904. * Here we are converting a number in the range of 100-9999
  905. *
  906. ITOR3
  907.        MOVB @HEX41,@VDPWD
  908.        LI   R0,5
  909. ITOR3A
  910.        CLR  R1
  911.        LI   R3,100
  912.        DIV  R3,R1
  913.        SWPB R1
  914.        MOVB R1,@VDPWD
  915.        SWPB R2
  916.        MOVB R2,@VDPWD
  917.        JMP  ITOR2
  918.  
  919.  
  920. ************************************************************
  921. *                                                          *
  922. *  I20TOR - Convert 20 bit integer to RADIX 100            *
  923. *                                                          *
  924. *  This procedure will convert a 20 bit integer to RADIX   *
  925. *  100 format.  The maximum size of a 20 bit integer is    *
  926. *  1,048,575.                                              *
  927. *                                                          *
  928. *  Input:  R1, R2 = 20 bit integer (high 12 bits of R1     *
  929. *                   must be zero).                         *
  930. *                                                          *
  931. *  Uses: R0, R1, R2, R3                                    *
  932. *                                                          *
  933. ************************************************************
  934.  
  935. I20TOR
  936.        MOVB @B08,@VDPWD        Store field length (8 bytes)
  937.  
  938.        CI   R1,0
  939.        JNE  I20TO2
  940.        CI   R2,0
  941.        JEQ  ITOR00           Number is zero
  942.        CI   R2,100
  943.        JL   ITOR1            Number is 1-99
  944.        CI   R2,10000
  945.        JL   ITOR3            Number is 100-9999
  946.        JMP  ITOR5A           Number is 10000-65535
  947.  
  948. I20TO2
  949.  
  950. * OK.  The number is greater than 65535.  See if it's
  951. * less than 1,000,000
  952. *
  953.        CI   R1,15
  954.        JL   ITOR5A           Number is < 983,040
  955.        CI   R2,16960
  956.        JL   ITOR5A
  957.  
  958. **
  959. *
  960. * Here we handle numbers 1,000,000-1,048,575
  961. *
  962. **
  963.  
  964. I20TO5 MOVB @HEX43,@VDPWD
  965.        LI   R0,3
  966.        MOVB @B01,@VDPWD
  967.        CLR  R1
  968.        AI   R2,-16960
  969.        JMP  ITOR5B
  970.  
  971. HEX40  BYTE >40
  972. HEX41  BYTE >41
  973. HEX42  BYTE >42
  974. HEX43  BYTE >43
  975.